/****************************************************************************\
 * @file     BR_Error.h
 * @author   傅帅
 * @date     2019/12/26
 * @brief    错误管理任务
 *
 ******************************************************************************
 * @note    用将32个错误分4组，每组错误被抛出时执行相同的处理函数

            创建错误：        BR_ErrorHandler_t my_error;
                             my_error = BR_xErrorCreate("my_error_name", 0/1/2/3);

            抛出错误：        BR_vErrorRaise(my_error);

            中断中抛出错误：  BaseType_t IfWoken
                             BR_vErrorRaiseFromISR(my_error, &IfWoken);

            错误处理：        自行实现void BR_vErrorHandlerGroup0/1/2/3(void){}的函数体

            清空错误：        BR_vClearErrorBits();
 ****************************************************************************/

#ifndef BR_ERRORMANAGER_H
#define BR_ERRORMANAGER_H

#include "FreeRTOS.h"
#include "task.h"


#define BR_ErrorManagerTaskPrio 16
#define BR_ErrorManagerTaskStkSize 512
#define BR_ERROR_FLASH_BASE ADDR_FLASH_SECTOR_10    /* 存ERROR的Flash地址 */

#define BR_ERROR_GROUP_0 0
#define BR_ERROR_GROUP_1 1
#define BR_ERROR_GROUP_2 2
#define BR_ERROR_GROUP_3 3
#define BR_ERROR_GROUP_0_BITS 0x000000FF
#define BR_ERROR_GROUP_1_BITS 0x0000FF00
#define BR_ERROR_GROUP_2_BITS 0x00FF0000
#define BR_ERROR_GROUP_3_BITS 0xFF000000

#define BR_ERROR_NO_ERROR     0xFFFFFFFF

typedef struct _BR_Error_t {
    char *ErrorName;                // 错误名称
    uint32_t ErrorBit;              // 错误对应的标志位
    uint8_t ErrorIndex;             // 错误对应的下标
    struct _BR_Error_t *pNext;      // 已抛出错误单向链表
}BR_Error_t;
typedef BR_Error_t* BR_ErrorHandler_t;

uint32_t BR_iGetErrorBits(void);
void BR_vClearErrorBits(void);
void BR_vErrorManagerTask(void);
void BR_vErrorManagerInit(void);
void BR_vErrorRaise(BR_ErrorHandler_t Error);
void BR_vErrorRaiseFromISR(BR_ErrorHandler_t Error, BaseType_t* pxHigherPriorityTaskWoken);
BR_ErrorHandler_t BR_xErrorCreate(char *ErrorName, uint8_t ErrorGroup);

void BR_vErrorHandlerGroup0(void);
void BR_vErrorHandlerGroup1(void);
void BR_vErrorHandlerGroup2(void);
void BR_vErrorHandlerGroup3(void);

extern TaskHandle_t BR_ErrorManagerTaskHandler;
extern BR_Error_t BR_RaisedErrorList;              // 已抛出错误的链表头

#endif
